#include "tcplistensocketimpl.h"
#include "tcpsocketimpl.h"

CTcpListenSocketImpl::CTcpListenSocketImpl()
{

}
CTcpListenSocketImpl::~CTcpListenSocketImpl()
{
	logi("CTcpListenSocketImpl::~CTcpListenSocketImpl");
}
std_method_impl CTcpListenSocketImpl::CloseIo(UINT rw)
{
	rc_assert(accpet_close() == S_SUCCESS, E_FAIL)
	return S_OK;
}
std_method_impl CTcpListenSocketImpl::OpenIo()
{
	//rc_assert(accpet_init() == S_SUCCESS, E_FAIL)
	return S_OK;
}
std_method_impl CTcpListenSocketImpl::BindIo()
{
	rc_assert(m_sock != INVALID_SOCKET, E_FAIL);
	rc_assert(accpet_assign(&m_sock) == S_SUCCESS, E_FAIL)
	return S_OK;
}
std_method_impl CTcpListenSocketImpl::CreateSock()
{
	HRESULT		hr = S_OK;
	m_sock = INVALID_SOCKET;
	m_sock = _createsock(PF_INET, SOCK_STREAM, IPPROTO_TCP);
	rc_assert(m_sock != INVALID_SOCKET, E_FAIL)
	return hr;
}
std_method_impl CTcpListenSocketImpl::CloseSock()
{
	HRESULT		hr = S_OK;

	rc_assert(m_sock != INVALID_SOCKET, E_FAIL)
	_closesock(m_sock);
	m_sock = INVALID_SOCKET;

	return hr;
}
std_method_impl CTcpListenSocketImpl::IsOpen()
{
	return accept_is_open() == S_SUCCESS ? S_OK : E_FAIL;
}

std_method_impl CTcpListenSocketImpl::AttachSock(_sock_t sock)
{
	rc_assert(sock != INVALID_SOCKET, E_FAIL)
	m_sock = sock;
	return S_OK;
}

std_method_type_impl(_sock_t) CTcpListenSocketImpl::DetachSock()
{
	return m_sock;
}
std_method_impl CTcpListenSocketImpl::SetOption(LPCSTR opt, int val)
{
	return E_NOTIMPL;
}
std_method_impl CTcpListenSocketImpl::GetOption(LPCSTR opt, int* val)
{
	return E_NOTIMPL;
}
std_method_impl CTcpListenSocketImpl::Listen(NET_ADDR addr, NET_PORT port)
{
	rc_assert(addr != NULL, E_FAIL)
	rc_assert(port != INVALID_NET_PORT, E_FAIL)

	int rc = S_SUCCESS;

	rc = accpet_bind(addr, port);
	rc_assert(rc == S_SUCCESS, E_FAIL)

	rc = accpet_listen();
	rc_assert(rc == S_SUCCESS, E_FAIL)

	return S_OK;
}
std_method_impl CTcpListenSocketImpl::Accept(IBase* pBase)
{
	HRESULT		hr = S_OK;

	TcpSocketPtr pAsynTcpScoket;
	hr = pBase->QueryInterface(IID_ITcpSocket, (void**)&pAsynTcpScoket);
	rc_assert(hr == S_OK, E_FAIL)

	CTcpSocketImpl *sock = static_cast<CTcpSocketImpl*>(pAsynTcpScoket.m_p);
	rc_assert(sock != NULL, E_FAIL)

	rc_assert(accpet_wait(sock->GetIoTcp(), pBase) == S_SUCCESS, E_FAIL)

	return hr;
}

std_method_impl CTcpListenSocketImpl::BindAccept(IBase* pAccept)
{
	rc_assert(pAccept != NULL, E_FAIL)
	return pAccept->QueryInterface(IID_IAcceptListen, (void**)&m_accept);
}
std_method_impl CTcpListenSocketImpl::UnBindAccpet()
{
	m_accept.dispose();
	return S_OK;
}
void CTcpListenSocketImpl::AcceptCB(void *data, event_id error_code, _sock_t s)
{
	c_assert(data != NULL)
	IBase* pBase = static_cast<IBase*>(data);

	c_assert(pBase != NULL)
	c_assert(m_accept != NULL)
	m_accept->Accept(pBase, s, error_code);
}

